/**
 * DOM 操作工具类
 * 提供统一的 DOM 元素操作方法
 */
class DomOperations {
    /**
     * @param {Object} page - Playwright 页面对象
     */
    constructor(page) {
        this.page = page;
    }

    /**
     * 检查元素是否存在
     * @param {string} selector - 选择器
     * @param {number} timeout - 超时时间（毫秒）
     * @returns {Promise<boolean>} 元素是否存在
     */
    async checkElementExists(selector, timeout = 5000) {
        try {
            const element = await this.page.waitForSelector(selector, { 
                state: 'attached',
                timeout 
            });
            return !!element;
        } catch (error) {
            console.log(`元素未找到: ${selector}`);
            return false;
        }
    }

    /**
     * 检查元素是否存在并返回元素
     * @param {string} selector - 选择器
     * @param {number} timeout - 超时时间（毫秒）
     * @returns {Promise<Object|null>} 如果元素存在返回元素对象，否则返回 null
     */
    async getElement(selector, timeout = 5000) {
        try {
            const element = await this.page.waitForSelector(selector, { 
                state: 'attached',
                timeout 
            });
            return element;
        } catch (error) {
            console.log(`元素未找到: ${selector}`);
            return null;
        }
    }

    /**
     * 移除元素
     * @param {string} selector - 元素选择器
     */
    async handleRemove(selector) {
        try {
            const exists = await this.checkElementExists(selector);
            if (exists) {
                await this.page.evaluate((sel) => {
                    const elements = document.querySelectorAll(sel);
                    elements.forEach(el => el.remove());
                }, selector);
                console.log(`已移除元素: ${selector}`);
            } else {
                console.log(`跳过移除，元素不存在: ${selector}`);
            }
        } catch (error) {
            console.error(`移除元素失败: ${selector}`, error);
        }
    }

    /**
     * 获取元素内容
     * @param {Object} element - Playwright元素
     * @param {string} attr - 要获取的属性
     * @returns {Promise<string>} 元素内容
     */
    async getElementContent(element, attr) {
        if (!element) return null;
        
        switch (attr) {
            case 'text':
                return await element.textContent();
            case 'html':
                return await element.innerHTML();
            case 'src':
            case 'href':
                return await element.getAttribute(attr);
            default:
                return await element.textContent();
        }
    }

    /**
     * 通过选择器获取元素内容
     * @param {string} selector - 元素选择器
     * @param {string} attr - 要获取的属性
     * @param {number} timeout - 超时时间（毫秒）
     * @returns {Promise<string>} 元素内容，如果元素不存在返回空字符串
     */
    async getElementContentBySelector(selector, attr, timeout = 5000) {
        try {
            const exists = await this.checkElementExists(selector, timeout);
            if (!exists) {
                console.log(`获取内容失败，元素不存在: ${selector}`);
                return "";
            }
            
            const element = await this.page.$(selector);
            const content = await this.getElementContent(element, attr);
            console.log(`成功获取元素内容: ${selector} -> ${content}`);
            return content || "";
            
        } catch (error) {
            console.error(`获取元素内容失败: ${selector}`, error);
            return "";
        }
    }

    /**
     * 获取文本内容
     * @param {string} selector - 选择器
     * @returns {Promise<string>} 文本内容
     */
    async getTextContent(selector) {
        try {
            const element = await this.page.$(selector);
            if (element) {
                return await element.textContent();
            }
        } catch (error) {
            console.warn(`获取文本内容失败: ${selector}`, error);
        }
        return null;
    }

    /**
     * 获取属性内容
     * @param {string} selector - 选择器
     * @param {string} attribute - 属性名
     * @returns {Promise<string>} 属性内容
     */
    async getAttributeContent(selector, attribute) {
        try {
            const element = await this.page.$(selector);
            if (element) {
                return await element.getAttribute(attribute);
            }
        } catch (error) {
            console.warn(`获取属性内容失败: ${selector} -> ${attribute}`, error);
        }
        return null;
    }

    /**
     * 获取HTML内容
     * @param {string} selector - 选择器
     * @returns {Promise<string>} HTML内容
     */
    async getHtmlContent(selector) {
        try {
            const element = await this.page.$(selector);
            if (element) {
                return await element.innerHTML();
            }
        } catch (error) {
            console.warn(`获取HTML内容失败: ${selector}`, error);
        }
        return null;
    }
}

module.exports = DomOperations;